package com.open.capacity.firebird.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.open.capacity.common.exception.service.ServiceException;
import com.open.capacity.common.model.*;
import com.open.capacity.common.util.PageUtil;
import com.open.capacity.common.web.CodeEnum;
import com.open.capacity.common.web.PageResult;
import com.open.capacity.common.web.Result;
import com.open.capacity.firebird.dao.FireBirdDao;
import com.open.capacity.firebird.service.FireBirdService;
import com.open.capacity.firebird.util.DataSourceUtil;
import com.open.capacity.firebird.util.FireBirdDriver;
import com.open.capacity.firebird.util.WordGenerate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import sun.misc.BASE64Encoder;

import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Service
public class FireBirdServiceImpl implements FireBirdService {

    @Autowired(required = false)
    FireBirdDao fireBirdDao;

    private String base64 = "data:image/jpg;base64,";

    @Override
    public Result connectFireBird(DB db) {
        Result result = FireBirdDriver.firebirdConn(db);
        if (result.getCode() == CodeEnum.SUCCESS.getCode()) {
            return DataSourceUtil.setFireBirdDataSource(db);
        }
        return result;
    }

    @Override
    public Result testConnect(DB db) {
        try {
            //尝试打开数据库文件
            return FireBirdDriver.firebirdConn(db);
        } catch (Exception e) {
            return Result.failed("连接出错");
        }

    }

    @Override
    public List<String> getTables(DB db) {
        Result result = connectFireBird(db);
        if (result.getCode() == CodeEnum.SUCCESS.getCode()) {
            List<String> tables = fireBirdDao.getDBTables();
            return tables;
        }
        return null;
    }

    @Override
    public List<TableField> getTableFields(Map map) {
        DBTable dbTable = JSON.parseObject((String) map.get("dbTable"), DBTable.class);
        DB db = JSON.parseObject((String) map.get("db"), DB.class);
        Result result = connectFireBird(db);
        if (result.getCode() == CodeEnum.SUCCESS.getCode()) {
            List<TableField> fields = fireBirdDao.getTableFields(dbTable.getTableName());
            return fields;
        }
        return null;
    }

    @Override
    public PageResult<AcheAndVolInfo> getAcheAndVolInfoList(Map map) {
        PageUtil.fireBirdPageParamConver(map, false);
        List<AcheAndVolInfo> list = fireBirdDao.getAcheAndVolInfoList(map).stream().map(a -> {
            a.setImg(base64 + readImg(a.getCandiNum() + ".jpg"));
            return a;
        }).collect(Collectors.toList());
        long count = fireBirdDao.getAcheAndVolInfoListCount(map);
        return PageResult.<AcheAndVolInfo>builder().code(CodeEnum.SUCCESS.getCode()).count(count).data(list).build();
    }

    @Override
    public PageResult<PhyExmInfo> getPhyExmInfoList(Map map) {
        PageUtil.fireBirdPageParamConver(map, false);
        List<PhyExmInfo> list = fireBirdDao.getPhyExmInfoList(map).stream().map(a -> {
            a.setImg(base64 + readImg(a.getCandiNum() + ".jpg"));
            return a;
        }).collect(Collectors.toList());
        long count = fireBirdDao.getPhyExmInfoListCount(map);
        return PageResult.<PhyExmInfo>builder().code(CodeEnum.SUCCESS.getCode()).count(count).data(list).build();
    }

    @Override
    public PageResult<RegisterInfo> getRegisterInfoList(Map map) {
        PageUtil.fireBirdPageParamConver(map, false);
        List<RegisterInfo> list = fireBirdDao.getRegisterInfoList(map).stream().map(a -> {
            a.setImg(base64 + readImg(a.getCandiNum() + ".jpg"));
            return a;
        }).collect(Collectors.toList());
        long count = fireBirdDao.getRegisterInfoListCount(map);
        return PageResult.<RegisterInfo>builder().code(CodeEnum.SUCCESS.getCode()).count(count).data(list).build();
    }

    @Override
    public Result getUnivInfo() {
        UnivInfo univInfo = fireBirdDao.getUnivInfo();
        return Result.succeed(univInfo, "success");
    }

    /**
     * 数据导出word方法封装
     * @param data 数据源
     * @param outPath 导出文件位置
     * @param tmplPath 模板文件位置
     * @param fileName 导出的文件名
     * @param tmplUrl 模板名
     * @param response 相应流
     * @return
     */
    @Override
    public Result export(String data, String outPath, String tmplPath, String fileName, String tmplUrl, HttpServletResponse response) {
        try {
            //如果以[]包含数据，则该string类型数据是一个数组
            if (data.startsWith("[") && data.endsWith("]")) {
                //fastjson将数据转换成map集合的列表数据
                List<Map> maps = JSONArray.parseArray(data, Map.class);
                if (maps.isEmpty())//判断是否有数据
                    return Result.failed("无数据");
                //将数据取出
                for (Map map : maps) {
                    String file = (String) map.get("candiNum") + map.get("candiName") + fileName;
                    String img = (String) map.get("img");
                    img = img.replace(base64,"");//去掉文件中开头的的base64标识
                    map.put("img",img);
                    //执行数据导为word文档
                    WordGenerate.WordGenerate(map, outPath, tmplPath, tmplUrl, file, response);
                }
                //如果集合中只有一个数据，则显示具体导出的文件地址以及文件名
                if (maps.size() == 1)
                    return Result.succeed("导出成功,请在 " + outPath + " 文件夹下查看名为:" + fileName + " 的文件");
                //批量导出则回显文件导出的位置
                return Result.succeed("导出成功,请在 " + outPath + " 文件夹下查看");
            }else {
                //如果是单个文件导出，则进行一下处理
                //将字符串数据转换为map集合
                Map map = JSONArray.parseObject(data, Map.class);
                fileName = (String) map.get("candiNum") + map.get("candiName") + fileName;
//                map.put("img",readImg(map.get("candiNum") + ".jpg"));
                String img = (String) map.get("img");
                img = img.replace(base64,"");
                map.put("img",img);
                //执行数据导为word文档
                WordGenerate.WordGenerate(map, outPath, tmplPath, tmplUrl, fileName, response);
                return Result.succeed("导出成功,请在 " + outPath + " 文件夹下查看名为:" + fileName + " 的文件");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return Result.failed("导出时遇到错误");
        }
    }

    @Override
    public Result getGradeCount(Map map) {
        long total = fireBirdDao.getGradeTotal();
        long count = fireBirdDao.getGradeCount(map);
        double percent = count / (double)total;
        return Result.succeed(percent,"");
    }

    @Override
    public Result setPhyExmConChart() {
        List<Map<String,Object>> list = new ArrayList<>();
        long total = fireBirdDao.getPhyExmConTotal();
        Map map1 = new HashMap();
        map1.put("name","合格");
        map1.put("y",(double)fireBirdDao.getPhyExmConCountById(1)/total);
        list.add(map1);
        Map map2 = new HashMap();
        map2.put("name","专业受限");
        map2.put("y",(double)fireBirdDao.getPhyExmConCountById(2)/total);
        list.add(map2);
        Map map3 = new HashMap();
        map3.put("name","院校可不予录取");
        map3.put("y",(double)fireBirdDao.getPhyExmConCountById(3)/total);
        list.add(map3);
        return Result.succeed(list,"");
    }

    @Override
    public Result setAdmissionPassChart() {
        List<Map<String,Object>> list = new ArrayList<>();
        Map map1 = new HashMap();
        map1.put("name","录取及格");
        long pass = fireBirdDao.getPassCount();
        map1.put("y",pass);
        list.add(map1);
        Map map2 = new HashMap();
        map2.put("name","未录取");
        map2.put("y",fireBirdDao.getAdmissionTotal()-pass);
        list.add(map2);
        return Result.succeed(list,"");
    }

    @Override
    public List<DocType> getDocTypeList() {
        return fireBirdDao.getDocTypeList();
    }

    @Override
    public Result admissionQuery(Map map) {
        try {
            //判断是否有该考生
            Long len = fireBirdDao.isExistCandidate(map);
            if (len!=null) {
                if (len>0){
                    //判断该考生是否被录取
                    AdmInfo admInfo = fireBirdDao.admissionQuery(map);
                    if (admInfo == null) {
                        return Result.succeed("很遗憾，您未被录取");
                    }
                    return Result.succeed("恭喜，您已被<b>" + admInfo.getAdmMajor() + "</b>专业录取！");
                }
            }
            return Result.failed("抱歉，您输入的身份信息有误或该考生号不存在");
        }catch (ServiceException e){
            throw new ServiceException(e);
        }
    }

    @Override
    public PageResult<AdmInfo> getAdmInfoList(Map map) {
        PageUtil.fireBirdPageParamConver(map, false);
        List<AdmInfo> list = fireBirdDao.getAdmInfoList(map);
        long count = fireBirdDao.getAdmInfoListCount(map);
        return PageResult.<AdmInfo>builder().code(CodeEnum.SUCCESS.getCode()).count(count).data(list).build();
    }

    /**
     * 读取图片将其转换为base64格式
     * @param imgUrl
     * @return
     */
    public String readImg(String imgUrl){
        byte[] picdata = null;
        InputStream in;
        //读取图片
        try {
            in = new FileInputStream("E:\\毕业设计\\Shandong\\1064400\\Download\\StudInfo0\\" + imgUrl);
            picdata = new byte[in.available()];
            in.read(picdata);
            in.close();
            BASE64Encoder encoder = new BASE64Encoder();
            return encoder.encode(picdata);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return "";
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
    }
}
